﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.DirectoryServices.ActiveDirectory;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using JiebaNet.Segmenter;
using myFileWatcher;
namespace SimpleDesktop
{
    public partial class Form2 : Form
    {
        private static BlockingCollection<FileEvent> fileEventQueue = new BlockingCollection<FileEvent>();
        //private static List<string> Openfiles  = new List<string>();
        int BUFFER_FILE = 8;
        private static string[] Openfiles = new string[8];
        
        FileSystemWatcher myWatcher;
        public Form2()
        {

            InitializeComponent();
            // 用于解决watcher和form线程的矛盾
            //System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
            listView4suggest.View = View.Details;
            listView4suggest.Columns.Add("Name", 250, HorizontalAlignment.Left);
            listView4suggest.Columns.Add("Path", 500, HorizontalAlignment.Left);
            listView4suggest.Columns.Add("Type", 100, HorizontalAlignment.Left);
            Utility.LoadTreeViewWithDirectories(treeView4menu, "C:\\temp");
            for (int i = 0; i < Openfiles.Length; i++)
            {
                Openfiles[i] = "";
            }

        }

        private void Form2_Load(object sender, EventArgs e)
        {
            var thread = new Thread(() =>
            {

                while (true)
                {
                    var processor = new EventProcessor((e) =>
                    {
                        // 此处必须写成代理
                        this.Invoke(new infoHandle(handleEvent), e);
                    }, (msg) =>
                    {
                        this.Invoke(new logrHandle(handleLog), msg);
                    });
                    var thread = new Thread(() =>
                    {
                        while (true)
                        {
                            var e = fileEventQueue.Take();
                            processor.ProcessEvent(e);

                        }
                    });
                    thread.IsBackground = true; // this ensures the thread does not block the process from terminating!
                    thread.Start();
                    Action<FileEvent> onEvent = (e) =>
                    {
                        fileEventQueue.Add(e);
                    };

                    Action<ErrorEventArgs> onError = (e) =>
                    {
                        if (e != null)
                        {
                            //Console.WriteLine("{0}|{1}", (int)ChangeType.LOG, e.GetException().ToString());
                            MessageBox.Show($"{(int)ChangeType.LOG}|{e.GetException().ToString()}");
                        }
                    };

                    var watcher = new FileWatcher();
                    myWatcher = watcher.Create("C:\\temp", onEvent, onError);
                    myWatcher.EnableRaisingEvents = true;
                    System.Threading.Thread.Sleep(1000000000);
                }
            });
            thread.IsBackground = true; // this ensures the thread does not block the process from terminating!
            thread.Start();
        }
        // watcher线程通过此代理实现对form2线程中控件的使用
        delegate void infoHandle(FileEvent e);
        delegate void logrHandle(string msg);
        // 代理的具体实现
        public void handleEvent(FileEvent e)
        {
            richtxtbox.AppendText($"| {e.changeType} | {e.path}\n");
            Utility.LoadTreeViewWithDirectories(treeView4menu, myWatcher.Path);
            List<string> OpenFiles = new List<string>();
            List<string> NoAccessFiles = new List<string>();
            (OpenFiles, NoAccessFiles) = Utility.CheckFilesAndPermissions(myWatcher.Path);
            Utility.showopenFile(richtxtbox4open_file, OpenFiles);
/*            if (OpenFiles.Count > 0)
            {
                Utility.SearchEverything("", listView4suggest);
            }*/
            int len = Openfiles.Length;
            for (int i = 0; i < OpenFiles.Count; i++)
            {
                Openfiles[(len + i) % BUFFER_FILE] = OpenFiles[i];
            }
        }

        public void handleLog(string msg) {
            richtxtbox.AppendText($"| {(int)ChangeType.LOG} | {msg}\n");
        }

        private void btn4ok_Click(object sender, EventArgs e)
        {
            // Validate provided path
            var path = txtbox4path.Text;
            //重新绘制文件treeView
            if (Directory.Exists(path))
            {
                Utility.LoadTreeViewWithDirectories(treeView4menu, path);
                myWatcher.Path = path;
            }

            List<string> targetFile = getTargetFiles();

            if (targetFile.Count > 0)
            {
                myWatcher.Filter = "empty";
                for (int i = 0; i < targetFile.Count; i++)
                {

                    myWatcher.Filters.Add("*." + targetFile[i]);
                }

            }
            else
            {
                myWatcher.Filter = "*.*";
            }



        }

        private void treeView4menu_AfterExpand(object sender, TreeViewEventArgs e)
        {
            e.Node.ImageIndex = 2;
            e.Node.SelectedImageIndex = 2;
        }

        private void treeView4menu_AfterCollapse(object sender, TreeViewEventArgs e)
        {
            e.Node.ImageIndex = 1;
            e.Node.SelectedImageIndex = 1;
        }

        private List<string> getTargetFiles()
        {
            List<string> selectedItemsList = new List<string>();
            // 源代码类
            for (int i = 0; i < chkListBox4src.Items.Count; i++)
            {
                // 如果该项被选中，则添加到列表中
                if (chkListBox4src.GetItemChecked(i))
                {
                    selectedItemsList.Add(chkListBox4src.Items[i].ToString());
                }
            }
            // 配置类
            for (int i = 0; i < chkListBox4config.Items.Count; i++)
            {
                // 如果该项被选中，则添加到列表中
                if (chkListBox4config.GetItemChecked(i))
                {
                    selectedItemsList.Add(chkListBox4config.Items[i].ToString());
                }
            }
            // 音频类
            for (int i = 0; i < chkListBox4audio.Items.Count; i++)
            {
                // 如果该项被选中，则添加到列表中
                if (chkListBox4audio.GetItemChecked(i))
                {
                    selectedItemsList.Add(chkListBox4audio.Items[i].ToString());
                }
            }
            // 视频类
            for (int i = 0; i < chkListBox4vedio.Items.Count; i++)
            {
                // 如果该项被选中，则添加到列表中
                if (chkListBox4vedio.GetItemChecked(i))
                {
                    selectedItemsList.Add(chkListBox4vedio.Items[i].ToString());
                }
            }
            // 图像类
            for (int i = 0; i < chkListBox4pic.Items.Count; i++)
            {
                // 如果该项被选中，则添加到列表中
                if (chkListBox4pic.GetItemChecked(i))
                {
                    selectedItemsList.Add(chkListBox4pic.Items[i].ToString());
                }
            }
            // 文档类
            for (int i = 0; i < chkListBox4doc.Items.Count; i++)
            {
                // 如果该项被选中，则添加到列表中
                if (chkListBox4doc.GetItemChecked(i))
                {
                    selectedItemsList.Add(chkListBox4doc.Items[i].ToString());
                }
            }
            return selectedItemsList;
        }

        private void btn4suggest_Click(object sender, EventArgs e)
        {

            //单独处理pdf
            string[] pdfFiles = Directory.GetFiles(myWatcher.Path, "*.pdf", SearchOption.AllDirectories);

            int len = Openfiles.Length;
            for (int i = 0; i < pdfFiles.Length; i++)
            {
                Openfiles[(len + i) % BUFFER_FILE] = pdfFiles[i];
            }

            // 清空原来推荐
            listView4suggest.Items.Clear();
            //从近期打开文件中筛选
            List<string> DocOpenFiles = Openfiles.Distinct().Where(file =>
                                                        (file.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase) ||
                                                        file.EndsWith(".doc", StringComparison.OrdinalIgnoreCase) ||
                                                        file.EndsWith(".docx", StringComparison.OrdinalIgnoreCase) ||
                                                        file.EndsWith(".ppt", StringComparison.OrdinalIgnoreCase) ||
                                                        file.EndsWith(".pptx", StringComparison.OrdinalIgnoreCase)) &&
                                                        !file.StartsWith("~$")
                                                    ).ToList();


            foreach (string file in DocOpenFiles)
            {
                JiebaSegmenter segmenter = new JiebaSegmenter();
                if (file.EndsWith(".pdf"))
                {
                    // 精确模式分词
                    var segments = segmenter.Cut(Utility.getTextfromPDF(file), cutAll: false);

                    string[] keyWords = Utility.ExtractKeywords(segments, 2);
                    for (int i = 0; i < keyWords.Length; i++)
                    {
                        Utility.SearchEverything(keyWords[i], listView4suggest);
                    }
                }
                else if (file.EndsWith(".docx") || file.EndsWith(".doc"))
                {
                    // 精确模式分词
                    var segments = segmenter.Cut(Utility.getTextfromWord(file), cutAll: false);

                    string[] keyWords = Utility.ExtractKeywords(segments, 2);
                    
                    for (int i = 0; i < keyWords.Length; i++)
                    {
                        Utility.SearchEverything(keyWords[i], listView4suggest);
                    }
                }
                else if (file.EndsWith(".pptx") || file.EndsWith(".ppt"))
                {
                    // 精确模式分词
                    var segments = segmenter.Cut(Utility.getTextfromPowerPoint(file), cutAll: false);

                    string[] keyWords = Utility.ExtractKeywords(segments, 2);
                    for (int i = 0; i < keyWords.Length; i++)
                    {
                        Utility.SearchEverything(keyWords[i], listView4suggest);
                    }
                }
            }
        }
    }
}
